﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HW4.GeocodeService;
using HW4.MovieService;
using Microsoft.Maps.MapControl.WPF;


namespace HW4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private string key = "Enter Bing crededentials here";

        private MapLayer m_PushpinLayer = new MapLayer();
        private List<string> locations = new List<string>();
        private List<string> locationCoords = new List<string>();
        private List<int> invalidLocations = new List<int>();

        private string GeocodeAddress(string address)
        {
            string results = "";
            GeocodeRequest geocodeRequest = new GeocodeRequest();

            // Set the credentials using a valid Bing Maps key
            geocodeRequest.Credentials = new GeocodeService.Credentials();
            geocodeRequest.Credentials.ApplicationId = key;

            // Set the full address query
            geocodeRequest.Query = address;

            // Set the options to only return high confidence results 
            ConfidenceFilter[] filters = new ConfidenceFilter[1];
            filters[0] = new ConfidenceFilter();
            filters[0].MinimumConfidence = GeocodeService.Confidence.High;

            // Add the filters to the options
            GeocodeOptions geocodeOptions = new GeocodeOptions();
            geocodeOptions.Filters = filters;
            geocodeRequest.Options = geocodeOptions;

            // Make the geocode request
            GeocodeServiceClient geocodeService = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
            GeocodeResponse geocodeResponse = geocodeService.Geocode(geocodeRequest);

            if (geocodeResponse.Results.Length > 0)
            {
                double lat = geocodeResponse.Results[0].Locations[0].Latitude;
                double lon = geocodeResponse.Results[0].Locations[0].Longitude;
                results = lat + ";" + lon;
            }
            else
                results = null;
            
            return results;
        }

        private void locationsToCoords()
        {
            locationCoords.Clear();
            invalidLocations.Clear();
            int locationIndex = 0;
            foreach(string location in locations)
            {
                string coords = GeocodeAddress(location);
                if (coords != null)
                    locationCoords.Add(coords);
                else
                    invalidLocations.Add(locationIndex);
                locationIndex++;
            }
            foreach(int index in invalidLocations)
            {
                locations.RemoveAt(index);
            }
        }

        private void locationsToMap(List<string> coords)
        {
            int locationIndex = 0;
            foreach(string coord in coords)
            {
                string[] digits = coord.Split(';');
                double latitude = double.Parse(digits[0].Trim(), System.Globalization.NumberStyles.Any);
                double longitude = double.Parse(digits[1].Trim(), System.Globalization.NumberStyles.Any);
                addPushpin(latitude, longitude, locationIndex);
                locationIndex++;
            }
        }

        private void addPushpin(double lat, double lon, int locationIndex)
        {
            Pushpin pushpin = new Pushpin();
            pushpin.ToolTip = locations.ElementAt(locationIndex);
            m_PushpinLayer.AddChild(pushpin, new Microsoft.Maps.MapControl.WPF.Location(lat, lon));
        }

        private void removePushpins()
        {
            int count = m_PushpinLayer.Children.Count;
            for (int i = 0; i < count; i++)
            {
                m_PushpinLayer.Children.RemoveAt(0);
            }
            map.Children.Remove(m_PushpinLayer);
        }

        private void getMovieLocations(String movieTitle)
        {
            MovieServiceClient ms = new MovieServiceClient();
            searchMoviesResponse1 response = ms.searchMovies(movieTitle);
            if (response != null && response.movies != null)
            {
                movieResponse movie = response.movies.ElementAt(0);
                label1.Content = "Showing locations mentioned in  the movie " + movie.title;
                foreach (string location in movie.locations)
                {
                    locations.Add(location);
                }
            }
            else label1.Content = "Search didn't find any movies";
        }

        private void clearData()
        {
            locations = new List<string>();
            locationCoords = new List<string>();
            removePushpins();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            clearData();
            if (textBox1.Text != "")
                getMovieLocations(textBox1.Text);
            else
                label1.Content = "Search must not be empty";
            
            locationsToCoords();
            locationsToMap(locationCoords);
            map.Children.Add(m_PushpinLayer);
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            clearData();
            locations.Add(textBox1.Text);
            locationsToCoords();
            locationsToMap(locationCoords);
            map.Children.Add(m_PushpinLayer);
        }
    }
}
